<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="icon" href="/favicon.ico" />
    <link rel="stylesheet" href="/assets/vendor/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="/assets/style/global.css" />
    <title>HTTP分片上传</title>
  </head>
  <body>
    <div id="app" class="app">
      <div class="container">
        <h2 class="text-center">HTTP分片上传</h2>
      </div>
      <div class="container">
        <form>
          <div class="form-group">
            <label for="exampleInputFile">文件:</label>
            <input id="file" class="form-control-file" type="file">
          </div>
          <div class="form-group">
            <label for="exampleInputFile">进度:</label>
            <div class="progress">
              <div id="progress" class="progress-bar" role="progressbar" style="width: 0%"></div>
            </div>
          </div>
          <button id="submit" type="button" class="btn btn-primary">上传</button>
        </form>
      </div>
    </div>
    <script src="/assets/vendor/crypto/crypto-js.min.js"></script>
    <script>
      let file, fileData, progress = 0
      // 获取 input file 的 dom 对象
      const inputFile = document.querySelector('#file')
      // 监听 change 事件
      inputFile.addEventListener('change', function() {
        file = this.files[0]
        progress = 0
        document.querySelector('#progress').style.width = progress + '%'
      })

      // 上传文件
      document.querySelector('#submit').addEventListener('click', function () {
        if (!file) {
          alert('请选择文件')
          return false
        }
        upload({ file })
      }, false)

      // 上传文件
      function upload({ file, chunkSize } = {}) {
        // 切片大小
        chunkSize = chunkSize || 1024 * 1024
        // 文件信息
        let chunkNumber = 0, fileSize = file.size, fileName = file.name, fileType = file.type;
        // 计算切片总数
        let chunkTotal = Math.ceil(fileSize / chunkSize);
        // 上传分片
        function uploadChunk(start) {
          const end = Math.min(start + chunkSize, fileSize);
          const chunk = file.slice(start, end);
          const formData = new FormData();
          formData.append('file', chunk);
          formData.append('chunkSize', chunkSize);
          formData.append('chunkNumber', chunkNumber);
          formData.append('chunkTotal', chunkTotal);
          formData.append('fileName', fileName);
          formData.append('fileSize', fileSize);
          formData.append('fileType', fileType);
          formData.append('sha256', CryptoJS.SHA256(chunk).toString());

          fetch('/upload-chunk', {
            method: 'POST',
            body: formData
          }).then(response => {
            if (response.ok) {
              chunkNumber++
              progress = ((chunkNumber / chunkTotal) * 100).toFixed(2)
              document.querySelector('#progress').style.width = progress + '%'
              if (chunkNumber < chunkTotal) {
                uploadChunk(chunkNumber * chunkSize)
              } else {
                console.log(':smile:上传完成')
              }
            } else {
              console.error('Upload failed')
            }
          }).catch(error => {
            console.error('Upload error', error)
          })

          // 原生js发请求
          // let xhr = new XMLHttpRequest();
          // xhr.onreadystatechange = function() {
          //   if (this.readyState == 4 && this.status == 200) {

          //   }
          // }
          // xhr.open('post', '/upload-chunk', true);
          // xhr.send(formData);

          // 使用jquery,需要将contentType，processData设置为false
          //   $.ajax({
          //       url: '/upload-chunk',
          //       type: 'post',
          //       data: formData,
          //       processData: false,
          //       contentType: false
          //   }).success(res=>{

          //   }).error(err=>{

          //   })
        }

        uploadChunk(0)
      }
    </script>
  </body>
</html>